/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.mzk.oai.metadataRepository.harvest.tei.svnManager;

import cz.mzk.kramerius.commons.Dom4jUtils;
import cz.mzk.oai.metadataRepository.harvest.tei.svn.MetadataDir;
import cz.mzk.oai.metadataRepository.metadata.DateStamp;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.tmatesoft.svn.core.SVNDirEntry;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNNodeKind;
import org.tmatesoft.svn.core.SVNProperties;
import org.tmatesoft.svn.core.io.SVNRepository;

/**
 *
 * @author Martin Řehánek (rehan at mzk.cz)
 */
public class Connector {

    private static final Logger logger = Logger.getLogger(Connector.class.getName());
    private final SVNRepository repository;

    public Connector(String url) throws SVNException {
        this.repository = RepositoryFactory.getRepository(url);
    }

    public long getLatestRevision() throws SVNException {
        return repository.getLatestRevision();
    }

    public List<Long> getSortedRevisions(DateStamp from, DateStamp until) throws SVNException {
        return new GetSortedRevisionsAction(repository).run(from, until);
    }

    public void printRepositoryInfo() throws SVNException {
        System.out.println("Repository Root: " + repository.getRepositoryRoot(true));
        System.out.println("Repository UUID: " + repository.getRepositoryUUID(true));
        System.out.println("latest revision: " + repository.getLatestRevision());
    }

    public List<MetadataDir> getMetadataDirs(Long revision) throws SVNException {
        List<MetadataDir> result = new ArrayList<MetadataDir>();
        Collection entries = repository.getDir("", revision, null, (Collection) null);
        Iterator iterator = entries.iterator();
        while (iterator.hasNext()) {
            SVNDirEntry entry = (SVNDirEntry) iterator.next();
            if (entry.getKind() == SVNNodeKind.DIR) {
                //System.err.println("revision: " + entry.getRevision());
                MetadataDir dir = new MetadataDir(entry.getName());
                result.add(dir);
            } else {
                logger.log(Level.WARNING, "Not a directory {0}", entry.getName());
            }
        }
        return result;
    }

    public List<String> getUpdatedTeiFilesInDir(MetadataDir dir, long revision) throws SVNException {
        return getTeiFilesInDir(dir, revision, true);
    }

    public List<String> getAllTeiFilesInDir(MetadataDir dir, long revision) throws SVNException {
        return getTeiFilesInDir(dir, revision, false);
    }

    private List<String> getTeiFilesInDir(MetadataDir dir, long revision, boolean addOnlyUpdatedInRevision) throws SVNException {
        List<String> result = new ArrayList<String>();
        Collection entries = repository.getDir("".concat(dir.getName()), revision, null, (Collection) null);
        Iterator iterator = entries.iterator();
        while (iterator.hasNext()) {
            SVNDirEntry entry = (SVNDirEntry) iterator.next();
            if (isTeiFile(entry)) {
                if (addOnlyUpdatedInRevision) {
                    if (entry.getRevision() == revision) {
                        result.add(entry.getName());
                    }
                } else {
                    result.add(entry.getName());
                }
            }
        }
        return result;
    }

    private boolean isTeiFile(SVNDirEntry entry) {
        return (entry.getKind() == SVNNodeKind.FILE)
                && (entry.getName().endsWith(".tei.xml"));
    }

    public Document getXmlContent(MetadataDir metadataDir, String filename, long revision) throws DocumentException, SVNException {
        SVNProperties properties = new SVNProperties();
        String path = buildPath(metadataDir, filename);
        //System.out.println("path: " + path);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        repository.getFile(path, revision, (SVNProperties) properties, out);
        ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
        return Dom4jUtils.loadDocument(in, false);
    }

    private String buildPath(MetadataDir metadataDir, String filename) {
        return File.separator + metadataDir.getName() + File.separator + filename;
    }
}
